package com.cjb.cloudsystem.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cjb.cloudsecurity.userMsg.entity.UserDetail;
import com.cjb.cloudsystem.convert.SysMenuConvert;
import com.cjb.cloudsystem.entity.SysMenu;
import com.cjb.cloudsystem.enums.SuperAdminEnum;
import com.cjb.cloudsystem.mapper.SysMenuMapper;
import com.cjb.cloudsystem.service.SysMenuService;
import com.cjb.cloudsystem.vo.SysMenuVO;
import com.cjb.common.common.constant.Constant;
import com.cjb.common.mybatisUtil.impl.BaseRepositoryImpl;
import com.cjb.common.query.DelEnum;
import com.cjb.common.util.ChangeTypeUtil;
import com.cjb.common.util.Common;
import com.cjb.common.util.JsonUtils;
import com.cjb.common.util.TreeUtils;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author chenjinbin
 * @Package IntelliJ IDEA
 * @Class SysMenusServiceImpl
 * @Date 2023-07-27 21:41
 */
@Service
@AllArgsConstructor
public class SysMenuRepositoryImpl extends BaseRepositoryImpl<SysMenuMapper, SysMenu> implements SysMenuService {
    /**
     * 日志
     */
    private final static Logger log = LoggerFactory.getLogger(SysMenuRepositoryImpl.class);
    /*
     * 注入mapper层
     */
    private final SysMenuMapper sysMenuMapper;
    /**
     * 注入封装类
     */
    private final SysMenuConvert sysMenuConvert;

    /**
     * 单体保存
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public boolean save(SysMenu sysMenu) {
        if (Common.isEmpty(sysMenu.getId())){
            sysMenu.setDeleted(0);
        }
        if (sysMenu.getId() == null) {
            // 新增操作
            baseMapper.insert(sysMenu);
        } else {
            // 修改操作
            baseMapper.updateById(sysMenu);
        }
        return true;
    }

    /**
     * 批量保存
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public Integer listSave(List<SysMenu> sysMenu) {
        return sysMenuMapper.insertBatchSomeColumn(sysMenu);
    }

    /**
     * 批量更新
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public void listUpdate(List<SysMenu> sysMenu) {
        sysMenuMapper.insertBatchSomeColumn(sysMenu);
    }

    /**
     * 批量删除
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public void listDelete(List<SysMenu> sysMenu) {
        List<Long> collect = sysMenu.stream().map(SysMenu::getId)
                .distinct()
                .collect(Collectors.toList());
        sysMenuMapper.deleteBatchIds(collect);
    }

    /**
     * 通过id删除
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public int deleteById(Long id) {
        UpdateWrapper<SysMenu> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id",id)
                .set("deleted",1);
        return sysMenuMapper.update(null,updateWrapper);
    }

    /**
     * 单个查询
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public SysMenu queryById(Long id) {
        return sysMenuMapper.selectById(id);
    }

    @Override
    public Page queryPage(Page sysMenuPage, SysMenu sysMenu) {
        return sysMenuMapper.selectPage(sysMenuPage, getWrapper(sysMenu));
    }

    /**
     *查询属性
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    private LambdaQueryWrapper<SysMenu> getWrapper(SysMenu query) {
        LambdaQueryWrapper<SysMenu> wrapper = Wrappers.lambdaQuery();
        if (Common.isNotNull(query.getId())) {
            wrapper.eq(SysMenu::getId, query.getId());
        }
        if (Common.isNotNull(query.getPid())) {
            wrapper.eq(SysMenu::getPid, query.getPid());
        }
        if (Common.isNotNull(query.getName())) {
            wrapper.eq(SysMenu::getName, query.getName());
        }
        if (Common.isNotNull(query.getUrl())) {
            wrapper.eq(SysMenu::getUrl, query.getUrl());
        }
        if (Common.isNotNull(query.getAuthority())) {
            wrapper.eq(SysMenu::getAuthority, query.getAuthority());
        }
        if (Common.isNotNull(query.getType())) {
            wrapper.eq(SysMenu::getType, query.getType());
        }
        if (Common.isNotNull(query.getOpenStyle())) {
            wrapper.eq(SysMenu::getOpenStyle, query.getOpenStyle());
        }
        if (Common.isNotNull(query.getIcon())) {
            wrapper.eq(SysMenu::getIcon, query.getIcon());
        }
        if (Common.isNotNull(query.getSort())) {
            wrapper.eq(SysMenu::getSort, query.getSort());
        }
        if (Common.isNotNull(query.getVersion())) {
            wrapper.eq(SysMenu::getVersion, query.getVersion());
        }
        wrapper.eq(SysMenu::getDeleted, DelEnum.NO_DEL.getCode());

        if (Common.isNotNull(query.getCreator())) {
            wrapper.eq(SysMenu::getCreator, query.getCreator());
        }
        if (Common.isNotNull(query.getCreateTime())) {
            wrapper.eq(SysMenu::getCreateTime, query.getCreateTime());
        }
        if (Common.isNotNull(query.getUpdater())) {
            wrapper.eq(SysMenu::getUpdater, query.getUpdater());
        }
        if (Common.isNotNull(query.getUpdateTime())) {
            wrapper.eq(SysMenu::getUpdateTime, query.getUpdateTime());
        }
        wrapper.orderByDesc(SysMenu::getId);
        return wrapper;
    }
    /**
     * 返回全部信息
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public List<SysMenuVO> returnAllData() throws Throwable {
        LambdaQueryWrapper<SysMenu> wrapper = Wrappers.lambdaQuery();
        wrapper.isNotNull(SysMenu::getType);
        wrapper.eq(SysMenu::getDeleted,DelEnum.NO_DEL.getCode());
        wrapper.orderByAsc(SysMenu::getSort);
        List<SysMenu> menus = sysMenuMapper.selectList(wrapper);
        List<SysMenuVO> list = new ArrayList<>();
        menus.forEach(m ->{
            SysMenuVO vo = new SysMenuVO();
            try {
                ChangeTypeUtil.copyNonNullProperties(m,vo);
            } catch (Throwable e) {
                throw new RuntimeException(e);
            }
            list.add(vo);
        });
        List<SysMenuVO> build = TreeUtils.build(list, Constant.ROOT);
        log.info("打印树形表单 {}", JsonUtils.toJsonString(build));
        return build;
    }

    /**
     * 创建用户方法
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public Set<String> getUserAuthority(UserDetail user) {
        // 系统管理员，拥有最高权限
        List<String> authorityList;
        Set<String> permsSet = new HashSet<>();
        if (Common.isNotEmpty(user)&&Common.isNotNull(user.getSuperAdmin())){
            if (user.getSuperAdmin().equals(SuperAdminEnum.YES.getValue())) {
                authorityList = baseMapper.getAuthorityList();
            } else {
                authorityList = sysMenuMapper.getAuthorityList();
            }
            // 用户权限列表
            for (String authority : authorityList) {
                if (StrUtil.isBlank(authority)) {
                    continue;
                }
                permsSet.addAll(Arrays.asList(authority.trim().split(",")));
            }
        }


        return permsSet;
    }

    /**
     * 用户菜单列表
     *
     * @param user 用户
     * @param type 菜单类型
     */
    @Override
    public List<SysMenuVO> getUserMenuList(UserDetail user, Integer type) {
        List<SysMenu> menuList;
        // 系统管理员，拥有最高权限
        if (Common.isNotEmpty(user) && user.getSuperAdmin().equals(SuperAdminEnum.YES.getValue())) {
            menuList = baseMapper.getMenuList(type);
        } else {
            menuList = baseMapper.getUserMenuList(user.getId(), type);
        }
        List<SysMenuVO> sysMenuVOS = sysMenuConvert.convertList(menuList);
        return TreeUtils.build(sysMenuVOS, Constant.ROOT);
    }





}